# eg:
# def IAmDecorator(foo):
#     '''我是一个装饰函数'''
#     pass
#
# @IAmDecorator
# def tobeDecorated(test):
#     '''我是被装饰函数'''
#     pass
# 或者
# tobeDecorated = IAmDecorator(tobeDecorated)

'''
Python 中，装饰器分为两种，分别是“函数装饰器”和“类装饰器”，
其中又以“函数装饰器”最为常见，“类装饰器”则用得很少
'''
# def IAmFakeDecorator(fun):
#     print("我是一个假的装饰器")
#     return fun

# @IAmFakeDecorator
# def func():
#     print("我是原函数")
# func = IAmFakeDecorator(func)
# func()

# def IAmDecorator(fun):
#     def wrapper(*args, **kw):
#         print("我是一个装饰器")
#         return fun
#     return wrapper
#
# @IAmDecorator
# def func(h):
#     print("我是原函数")

# 传入一个参数才能够发生正确的调用原函数
# func()(1)

# Python 内置模块functools中的wraps工具，实现“在使用装饰器扩展函数功能的同时，保留原函数属性”这一目的
import  functools
def IAmDecorator(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kw):
        print("我是一个装饰器")
        return fun
    return wrapper

@IAmDecorator
def func(h):
    print("我是原函数")

print(func.__name__)

# 类装饰器
# @ClassDecorator
# class Foo:
#     pass

'''
__init__方法负责在初始化类实例的时候，将传入的函数或类绑定到这个实例上；
而__call__方法则与一般的函数装饰器差不多，连构造都没什么两样，可以认为__call__方法就是一个函数装饰器
'''
